//
//  PlayManager.m
//  Education
//  Created by Eric on 17/6/22.

#import "PlayManager.h"

@interface PlayManager()


@end

@implementation PlayManager

//单例
+ (PlayManager *)sharPlayManager{
    
    static PlayManager *playManager = nil;
    static dispatch_once_t onceToken;
    
    dispatch_once(&onceToken, ^{
        playManager = [[PlayManager alloc] init];
    });
    
    return playManager;
    
}

-(instancetype)init {
    
    self = [super init];
    
    if (self) {
        
        //创建音频会话用来处理各种播放状况。
        _avsession = [AVAudioSession sharedInstance];
        
        //创建单例对象并且使其设置为活跃状态.
        [_avsession setActive:YES error:nil];
        
        //设置播放通道
        [_avsession setCategory:AVAudioSessionCategoryPlayAndRecord
                    withOptions:AVAudioSessionCategoryOptionDefaultToSpeaker
                          error:nil];

        //监听播放通道的变化
        [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(audioRouteChangeListenerCallback:) name:AVAudioSessionRouteChangeNotification object:nil];
    }
    
    return self;
}

//切换歌曲或者为播放器加载资源的方法
- (void)playerWithURL:(NSString *)usrString{
    
    //创建url对象
    NSURL *musicURL = [NSURL URLWithString:usrString];
    //初始化播放单元
    AVPlayerItem  *playerItem = [[AVPlayerItem alloc] initWithURL:musicURL];
    
    //通过判断当前播放器有没有播放单元来决定是否移除观察者，如果播放单元存在，移除观察者,如果不存在，就不需要
    if (self.myPlayer.currentItem) {
        
        //说明有，需要移除观察者
        dispatch_async(dispatch_get_main_queue(), ^{
            [self.myPlayer.currentItem removeObserver:self forKeyPath:@"status"];
            [self.myPlayer replaceCurrentItemWithPlayerItem:playerItem];
            //为item的status属性添加观察值
            [playerItem addObserver:self forKeyPath:@"status" options:NSKeyValueObservingOptionNew context:nil];
        });

    }else{
        
        //说明没有播放单元，不需要任何操作
        //将播放单元设置给播放器
        self.myPlayer = [[AVPlayer alloc] initWithPlayerItem:playerItem];
        self.myPlayer.volume = 1.0;
        WeakSelf(self);
        DebugLog(@"设置媒体音量值---------------------%f",self.myPlayer.volume);
        [self.myPlayer addPeriodicTimeObserverForInterval:CMTimeMake(1, 1) queue:dispatch_get_main_queue() usingBlock:^(CMTime time) {
            
            [weakself playTimeDeal];
            
        }];
        //设置最小缓存
        [self.myPlayer setAutomaticallyWaitsToMinimizeStalling:NO];
        
        //监测歌曲是否播放完毕
        [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(musicFinsh:) name:AVPlayerItemDidPlayToEndTimeNotification object:nil];
        //为item的status属性添加观察值
        [playerItem addObserver:self forKeyPath:@"status" options:NSKeyValueObservingOptionNew context:nil];
    }

    [self play];
}
- (NSUInteger)getDurationWithUrlString:(NSString *)urlStr {
    NSDictionary *dic = @{AVURLAssetPreferPreciseDurationAndTimingKey:@(YES)};
    AVURLAsset *audioAsset = [AVURLAsset URLAssetWithURL:[NSURL URLWithString:urlStr] options:dic];
    CMTime audioDuration = audioAsset.duration;
    Float64 audioDurationSeconds = CMTimeGetSeconds(audioDuration);
    return (NSUInteger)audioDurationSeconds;
}

//歌曲播放完成调用的方法
- (void)musicFinsh:(NSNotification *)sender{
    if (self.delegate && [self.delegate respondsToSelector:@selector(musicFinsh)]) {
        [self.delegate musicFinsh];
    }

    DebugLog(@"播放完成✅");
}

//是否是在播放状态
- (Boolean)isPlaying
{
    return self.myPlayer.timeControlStatus == AVPlayerTimeControlStatusPlaying;
}
//播放
- (void)play{
    
    dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(0.2 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
        [self.myPlayer play];
    });
    
}

//暂停
- (void)pause{
    [self.myPlayer pause];
}
- (void)playTimeDeal
{
    if (self.myPlayer.currentItem.status == AVPlayerItemStatusReadyToPlay) {
       
        //CMTime:是用来表示多媒体资源时长的单位，它有两个重要的属性  value：总帧数 timerScale:每秒多少帧
        if (self.myPlayer.currentItem.duration.value) {
            
            //保证除数不为0，如果除数为0，就会崩溃
            float currentSeconds = (self.myPlayer.currentTime.value * 1.0) / (self.myPlayer.currentTime.timescale * 1.0);
            float durationSeconds = (self.myPlayer.currentItem.duration.value * 1.0) / (self.myPlayer.currentItem.duration.timescale * 1.0);
            
            double times = CMTimeGetSeconds(self.myPlayer.currentTime);
            
            //得到slider的进度
            if (durationSeconds) {
                float progressValue = currentSeconds / durationSeconds;
                //是否指定代理，代理方法是否实现
                if (self.delegate && [self.delegate respondsToSelector:@selector(playerWithPlayer:progress:duration: currentTime:)]) {
                    [self.delegate playerWithPlayer:self.myPlayer progress:progressValue duration:durationSeconds currentTime:times];
                }
            }
        }
        
    }
}

//用蓝牙还是用喇叭播放，模式切换
-(void)playwhichway:(BOOL)speaker
{
    if(speaker)
    {
        [_avsession setCategory:AVAudioSessionCategoryPlayAndRecord
                    withOptions:AVAudioSessionCategoryOptionDefaultToSpeaker
                          error:nil];
    }else
    {
        [_avsession setCategory:AVAudioSessionCategoryPlayback
                    withOptions:AVAudioSessionCategoryOptionAllowBluetooth
                          error:nil];
    }
    
}

//通知方法的实现 --- 监听通道的改变
- (void)audioRouteChangeListenerCallback:(NSNotification*)notification {
    
    NSDictionary *interuptionDict = notification.userInfo;
    NSInteger routeChangeReason = [[interuptionDict valueForKey:AVAudioSessionRouteChangeReasonKey] integerValue];
    switch (routeChangeReason) {
        case AVAudioSessionRouteChangeReasonNewDeviceAvailable: //耳机或传统蓝牙连接上了
            DebugLog(@"AVAudioSessionRouteChangeReasonNewDeviceAvailable,耳机插入/蓝牙连接%@", [_avsession.currentRoute.outputs firstObject].portType);
            
            break;
            
        case AVAudioSessionRouteChangeReasonOldDeviceUnavailable://耳机或传统蓝牙断开了
            DebugLog(@"AVAudioSessionRouteChangeReasonOldDeviceUnavailable,耳机拔出/蓝牙断开%@", [_avsession.currentRoute.outputs firstObject].portType);
            
            break;
            
        case AVAudioSessionRouteChangeReasonCategoryChange://其它播放想要加入
            
            DebugLog(@"播放通道的改变：AVAudioSessionRouteChangeReasonCategoryChange,%@",[_avsession.currentRoute.outputs firstObject].portType);
            
            break;
            
        default:
            
            DebugLog(@"other reason");
            [_avsession setCategory:AVAudioSessionCategoryPlayback
                        withOptions:AVAudioSessionCategoryOptionDefaultToSpeaker
                              error:nil];
            break;
    }
    
}

- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary<NSString *,id> *)change context:(void *)context
{
  
    //播放的状态
    if ([keyPath isEqualToString:@"status"]) {
        //取出新值
        AVPlayerItemStatus status = [change[NSKeyValueChangeNewKey] intValue];
        if (self.delegate && [self.delegate respondsToSelector:@selector(playStateChange:)]) {
            [self.delegate playStateChange:status];
        }

        switch (status) {
            case AVPlayerItemStatusFailed:
                DebugLog(@"播放资源失败");
                
                break;
            case AVPlayerItemStatusReadyToPlay:
                DebugLog(@"可以播放了");
                [[NSNotificationCenter defaultCenter] postNotificationName:@"playerStatueChange" object:self.delegate];
                //当前已经播放的时长
                [self.myPlayer rate];
                break;
            case AVPlayerItemStatusUnknown:
                DebugLog(@"出现未知错误");
                
                break;
            default:
                break;
        }
    }
}
- (void)setUseTime:(double)useTime
{
    _useTime = useTime;
    if (useTime == 0) {
        self.isBeginTest = NO;
    }
    
    
    
}
//不管何时,只要有通知中心的出现,在dealloc的方法中都要移除所有观察者.
-(void)dealloc{
    [[NSNotificationCenter defaultCenter] removeObserver:self];
}


@end

